﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace GameNode
{
    class NodeGameLogic
   {
       private readonly GameField gameField;
       private readonly Drawer drawer;
       private readonly Random rnd;
       private List<ConsoleNode> nodes;
       private List<ConsoleNode> winnerNodes;
       private ConsoleNode target;
       private int nodeCount;

        public NodeGameLogic(GameField gameField, Drawer drawer, int nodeCount)
        {
            this.gameField = gameField;
            this.drawer = drawer;
            this.nodeCount = nodeCount;

            rnd = new Random();
            nodes = new List<ConsoleNode>();
            winnerNodes = new List<ConsoleNode>();
            target = GenerateRandomTarget((char) 1, ConsoleColor.White);

        }


        public void StartGame()
        {
            GenerateRandomNodes();
            MaksimGameNode maksnode = new MaksimGameNode(1,1,'M', ConsoleColor.Green);
            SmartNode smart = new SmartNode(2, 2, 'N', ConsoleColor.Yellow);
            //nodes.Add(maksnode);
            nodes.Add(smart);

            bool isGameOver = false;
            do
            {
                Console.Clear();
                bool isNewRound = false;
                do
                {
                    drawer.DrawGameField(gameField, '0');
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        nodes[i].Move(CheckPosition);
                    }
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (IsNodeOnTarget(nodes[i]))
                        {
                            winnerNodes.Add(nodes[i]);
                            drawer.DrawListAndMessage(winnerNodes, gameField, 5, "Winners");
                            nodes.RemoveAt(i);
                            if (nodes.Count == 1)
                            {
                                drawer.DrawListAndMessage(nodes, gameField, 15, "Loosers");
                                isNewRound = true;
                                RandomPlacement(winnerNodes);
                            }
                        }
                    }
                    drawer.DrawNodeList(nodes);
                    drawer.DrawNode(target);
                    Thread.Sleep(100);
                }
                while (!isNewRound);

                Console.ReadKey();
                
                if (winnerNodes.Count == 1)
                {
                    isGameOver = true;
                }
                else
                {
                    nodes = winnerNodes;
                    winnerNodes = new List<ConsoleNode>();
                }

            } while (!isGameOver);
        }
    
       private ConsoleNode GenerateRandomNode(int nodeCount)
       {

           int randomX = 0;
           int randomY = 0;
           do
           {
               randomX = rnd.Next(gameField.X, gameField.Width + gameField.X);
               randomY = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

           } while (!IsPositionFree(randomX, randomY));

            return  new ConsoleNode(randomX, randomY, (char)(nodeCount + 41),
                                        (ConsoleColor)rnd.Next(1, 15));
       }

        private ConsoleNode GenerateRandomTarget(char symbol, ConsoleColor color)
        {

            int randomX = 0;
            int randomY = 0;
            do
            {
                randomX = rnd.Next(gameField.X, gameField.Width + gameField.X);
                randomY = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

            } while (!IsPositionFree(randomX, randomY));

            return new ConsoleNode(randomX, randomY, symbol, color);
        }

        private void GenerateRandomNodes()

        {
            for (int i = 0; i < nodeCount; i++)
            {
                nodes.Add(GenerateRandomNode(i));
            }
        }

       private bool IsPositionFree(int x, int y)
       {
            foreach (var nd in nodes)
            {
                if (nd.IsOnPossition(x,y))
                    return false;
            }
           return true;
       }

       //private void MoveNodeRandomly(ConsoleNode node)
       //{
       //     int randomMove = rnd.Next(1, 5);
       //     switch (randomMove)
       //     {
       //         case 1:
       //             {
       //                 //MoveUp
       //                 if (IsPositionFree(node.X, node.Y - 1) &&
       //                     gameField.IsOnField(node.X, node.Y - 1))
       //                     node.MoveUp();
       //             }
       //             break;

       //         case 2:
       //             {
       //                 //MoveDown
       //                 if (IsPositionFree(node.X, node.Y + 1) &&
       //                     gameField.IsOnField(node.X, node.Y + 1))
       //                     node.MoveDown();
       //             }
       //             break;

       //         case 3:
       //             {
       //                 //MoveLeft
       //                 if (IsPositionFree(node.X - 1, node.Y) &&
       //                     gameField.IsOnField(node.X - 1, node.Y))
       //                     node.MoveLeft();
       //             }
       //             break;

       //         case 4:
       //             {
       //                 //MoveRight
       //                 if (IsPositionFree(node.X + 1, node.Y) &&
       //                     gameField.IsOnField(node.X + 1, node.Y))
       //                     node.MoveRight();
       //             }
       //             break;
       //     }
       //}

       private bool IsNodeOnTarget(ConsoleNode node)
       {
           if (node.X == target.X && node.Y == target.Y)
               return true;
           return false;
       }

        private void RandomPlacement(List<ConsoleNode> nodes)
        {
            foreach (var node in nodes)
            {
                do
                {
                    node.X = rnd.Next(gameField.X, gameField.Width + gameField.X);
                    node.Y = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

                } while (!IsPositionFree(node.X,node.Y));
            }
        }

       private Position CheckPosition(int x, int y)
       {
           if (!IsPositionFree(x, y))
               return Position.Node;
           if (!gameField.IsOnField(x, y))
               return Position.Border;
           return Position.Free;
       }

   }

    public enum Position
    {
        Node,
        Border,
        Free
    }
}
